// 所有工具函数都写到这里
const jwt = require('jsonwebtoken')
const config = require('./config')
const express = require('express')
const multer = require('multer')
const moment = require('moment')
const fs = require('fs')
const md5 = require('md5')

function parseToken(token) {
    try {
        // 3. 解析令牌，返回对象：{id:管理员ID, exp: 过期时间, crt：创建时间 ...}
        let data = jwt.verify(token, config.key)
        // 把解析的ID放到 req 上然后在下一个中羊件中就可以从 req 中取出来了 
        return data.id
    } catch (err) {
        return null
    }

}

// 解析令牌
function chkToken(req, res, next) {
    // 1. 取出令牌（在协议头的 authorization上）
    let token = req.headers.authorization
    if (token === undefined) {
        res.json({
            'ok': 0,
            'error': '令牌不存在！'
        })
    } else {
        // 2. 提取出令牌（令牌前有 Bearer 七个字符）
        token = token.replace('Bearer ', '')
        try {
            // 3. 解析令牌，返回对象：{id:管理员ID, exp: 过期时间, crt：创建时间 ...}
            let data = jwt.verify(token, config.key)
            // 把解析的ID放到 req 上然后在下一个中羊件中就可以从 req 中取出来了 
            req.userId = data.id
            // 进入下一个中间件
            next()
        } catch (err) {
            res.json({
                'ok': 0,
                'error': '令牌无效！'
            })
        }
    }
}

function chkAdminToken(req, res, next) {
    // 1. 取出令牌（在协议头的 authorization上）
    let token = req.headers.authorization
    if (token === undefined) {
        res.json({
            'ok': 0,
            'error': '令牌不存在！'
        })
    } else {
        // 2. 提取出令牌（令牌前有 Bearer 七个字符）
        token = token.replace('Bearer ', '')
        try {
            // 3. 解析令牌，返回对象：{id:管理员ID, exp: 过期时间, crt：创建时间 ...}
            let data = jwt.verify(token, config.admin_key)
            // 把解析的ID放到 req 上然后在下一个中羊件中就可以从 req 中取出来了 
            req.adminId = data.id
            // 进入下一个中间件
            next()
        } catch (err) {
            res.json({
                'ok': 0,
                'error': '令牌无效！'
            })
        }
    }
}

function jwtRouter() {
    // 创建路由
    let router = express.Router()
    // 把解析令牌的函数应用到这个路由上
    router.use(chkToken)
    // 返回路由
    return router
}

function jwtAdminRouter() {
    // 创建路由
    let router = express.Router()
    // 把解析令牌的函数应用到这个路由上
    router.use(chkAdminToken)
    // 返回路由
    return router
}

// 创建路由
const router = express.Router()
// 把解析令牌的函数应用到这个路由上
router.use(chkToken)


/* 上传图片相关 */

// 创建存储对象
const storage = multer.diskStorage({
    // 配置保存文件的路径
    destination: function (req, file, cb) {

        // 1.先获取今天的日期，格式：年月日，如：20191209
        let today = moment().format('YYYYMMDD')
        fs.access('./uploads', fs.constants.F_OK, (error) => {
            if (error) {
                fs.mkdir('uploads', (err) => {})
            }
            // 2. 判断 uploads 上是否有这个目录
            let dir = './uploads/' + today
            fs.access(dir, fs.constants.F_OK, (err) => {
                // 如果目录不存在就创建
                if (err) {
                    fs.mkdir(dir, (err) => {})
                }
                // 设置上传图片的目录为当前日期的目录
                cb(null, dir)
            });
        })

    },
    // 自定义上传文件名
    // req：请求对象
    // file：上传的文件信息
    filename: function (req, file, cb) {
        // 用当前时间戳做为新上传的文件名
        //           获取当前时间戳 (123445543)   + 从原图片中提取出图片的后缀名    a.jpg.png       b.png-->.png
        let newName = Date.now() + '.' + file.originalname.substr(file.originalname.lastIndexOf('.') + 1)
        cb(null, newName)
    }
})

// 创建一个上传图片
const upload = multer({
    storage, // 前面创建的存储对象
    // 最大尺寸限制
    limits: {
        fileSize: 1024 * 1024 * 4 // 最大 4M ，单位：字节
    },
    // 自定义上传过滤器
    fileFilter: (req, file, cb) => {
        // 文件类型
        if (['image/png', 'image/jpeg', 'image/jpg', 'image/gif'].indexOf(file.mimetype) !== -1)
            cb(null, true)
        else
            cb(new Error('不允许上传的类型'))
    }
})

function createLiveUrl() {
    const appName = 'czqclive'
    const streamName = parseInt(Math.random() * 10000)
    
    const pushDomain = config.live.pushDomain  // 推流域名
    const pullDomain = config.live.pullDomain  // 拉流域名
    const pushKey = config.live.pushKey
    const pullKey = config.live.pullKey

    const pushUrl = `rtmp://${pushDomain}/${appName}/${streamName}`  // 拼出原始推流地址
    const pullUrl = `rtmp://${pullDomain}/${appName}/${streamName}`  // 拉出原始播放地址
    
    let timeInt = Date.now().toString().substring(0,10)
    let expireAt = parseInt(timeInt) + 1800
    
    let pushstr = `/${appName}/${streamName}-${expireAt}-0-0-${pushKey}`
    let pushAuthKey = md5(pushstr)
    
    let pullstr = `/${appName}/${streamName}-${expireAt}-0-0-${pullKey}`
    let pullAuthKey = md5(pullstr)
    
    // 拼出最终地址
    let finalPushUrl = pushUrl + '?auth_key='+expireAt+'-0-0-' +pushAuthKey
    let finalPullUrl = pullUrl + '?auth_key='+expireAt+'-0-0-' +pullAuthKey

    return {
        push_url: finalPushUrl,
        pull_url: finalPullUrl,
        stream_name: streamName
    }
}


module.exports = {
    chkToken,
    router,
    jwtRouter,
    jwtAdminRouter,
    upload,
    createLiveUrl,
    parseToken
}